package il.ac.bgu.cs.heuristics.graph.pddl.parser;

import il.ac.bgu.cs.heuristics.graph.pddl.auxiliary.ContradictionResolver;
import il.ac.bgu.cs.heuristics.graph.pddl.parser.types.ITypedConstant;
import il.ac.bgu.cs.heuristics.graph.types.ISubstitution;

import java.io.IOException;
import java.io.InputStream;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.junit.Test;

public class ContradictionTests extends TestCase {

	// private static final String CONTRADICTIONS_FILE_NAME =
	// "contradictions.txt";
	// private static final String NO_CONTRADICTIONS_FILE_NAME =
	// "no_contradictions.txt";

	@Test
	public void testContradiction01() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		Assert.assertNotNull("contradictions file not found", in);
	}

	@Test
	public void testContradiction02() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			new ContradictionResolver(in);
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Different predicate names
	 */
	@Test
	public void testContradiction03() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ITypedConstant person = (ITypedConstant) ExpressionParser
					.parseTypedParameter("bobo - person");
			final ITypedConstant location = (ITypedConstant) ExpressionParser
					.parseTypedParameter("room - person");
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, person, location);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.PRESENT_PREDICATE, location, person);
			Assert.assertFalse(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Same Predicate name but different parameters
	 */
	@Test
	public void testContradiction04() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.PERSON_A,
					TestUtils.LOCATION_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.LOCATION_A,
					TestUtils.PERSON_B);
			Assert.assertFalse(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Same Predicate name but parameters are disjoint
	 */
	@Test
	public void testContradiction05() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.PERSON_A,
					TestUtils.LOCATION_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.LOCATION_B,
					TestUtils.PERSON_B);
			Assert.assertFalse(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Contradiction of <BR>
	 * (at ?X1 - object ?X2 - object),(at ?X2 - object ?X1 - object)
	 */
	@Test
	public void testContradiction06() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.PERSON_A,
					TestUtils.LOCATION_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.LOCATION_A,
					TestUtils.PERSON_A);
			Assert.assertTrue(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Contradiction of <BR>
	 * (at ?X1 - object ?X2 - object),(at ?X1 - object ?X3 - object)
	 */
	@Test
	public void testContradiction07() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.PERSON_A,
					TestUtils.LOCATION_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.PERSON_A,
					TestUtils.LOCATION_B);
			Assert.assertTrue(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Contradiction of <BR>
	 * (at ?X1 - object ?X2 - object),(at ?X1 - object ?X3 - object)
	 */
	@Test
	public void testContradiction07a() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.PERSON_A,
					TestUtils.LOCATION_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.AT_PREDICATE, TestUtils.PERSON_A,
					TestUtils.LOCATION_A);
			Assert.assertFalse(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Contradiction of <BR>
	 * (on-plane ?X1 - object),(not (on-vacation ?X1 - object))
	 */
	@Test
	public void testContradiction08() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_PLANE_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			Assert.assertFalse(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Contradiction of <BR>
	 * (on-plane ?X1 - object),(not (on-vacation ?X1 - object))
	 */
	@Test
	public void testContradiction09() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_PLANE_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_VACATION_PREDICATE, TestUtils.PERSON_B);
			Assert.assertFalse(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Contradiction of <BR>
	 * (on-plane ?X1 - object),(not (on-vacation ?X1 - object))
	 */
	@Test
	public void testContradiction10() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_PLANE_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.NOT_ON_VACATION_PREDICATE, TestUtils.PERSON_B);
			Assert.assertFalse(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	/**
	 * Contradiction of <BR>
	 * (on-plane ?X1 - object),(not (on-vacation ?X1 - object))
	 */
	@Test
	public void testContradiction11() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.CONTRADICTIONS_FILE_NAME);
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_PLANE_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.NOT_ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			Assert.assertTrue(resolver.resolve(sub1, sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	public void testIsNegate01() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.NO_CONTRADICTIONS_FILE_NAME);
		// the contradiction file is empty
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			Assert.assertFalse(sub1.isContradicting(sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	public void testIsNegate02() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.NO_CONTRADICTIONS_FILE_NAME);
		// the contradiction file is empty
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.NOT_ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			Assert.assertTrue(sub1.isContradicting(sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	public void testIsNegate03() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.NO_CONTRADICTIONS_FILE_NAME);
		// the contradiction file is empty
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.NOT_ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			Assert.assertTrue(sub1.isNegateSubstitution(sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	public void testIsNegate04() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.NO_CONTRADICTIONS_FILE_NAME);
		// the contradiction file is empty
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.NOT_ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.NOT_ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			Assert.assertFalse(sub1.isNegateSubstitution(sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	public void testIsNegate05() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.NO_CONTRADICTIONS_FILE_NAME);
		// the contradiction file is empty
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.NOT_ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_PLANE_PREDICATE, TestUtils.PERSON_A);
			Assert.assertFalse(sub1.isNegateSubstitution(sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

	public void testIsNegate06() {
		final InputStream in = ContradictionTests.class
				.getResourceAsStream(TestUtils.NO_CONTRADICTIONS_FILE_NAME);
		// the contradiction file is empty
		try {
			final ContradictionResolver resolver = new ContradictionResolver(in);
			final ISubstitution sub1 = TestUtils.createSubstitution(resolver,
					TestUtils.NOT_ON_VACATION_PREDICATE, TestUtils.PERSON_A);
			final ISubstitution sub2 = TestUtils.createSubstitution(resolver,
					TestUtils.ON_PLANE_PREDICATE, TestUtils.PERSON_B);
			Assert.assertFalse(sub1.isNegateSubstitution(sub2));
		} catch (IllegalArgumentException e) {
			Assert.fail(e.getMessage());
		} catch (IOException e) {
			Assert.fail(e.getMessage());
		}
	}

}
